import 'dart:io';
import 'dart:math';
import 'dart:convert';
import 'dart:async';


class CustomWebSocket {
  String _url;
  String _token;
  var _socket;
  Function()? onOpen;
  Function(dynamic msg)? onMessage;
  Function(int? code, String? reason)? onClose;
  CustomWebSocket(this._url,this._token);

  /***
   * socket 连接
   */
  connect() async {
    try{
      _socket = await _connectForSelfSignedCert(_url,_token);
      onOpen?.call();
      _socket.listen((data) {
        onMessage?.call(data);
      },onDone: (){
        onClose?.call(_socket.closeCode, _socket.closeReason);
      });
    }catch(e){
      onClose?.call(500, e.toString());
    }
  }

  send(data) {
    if(_socket != null){
      _socket.add(data);
    }
  }

  Future<WebSocket> _connectForSelfSignedCert(url, token) async {
    try {
      // Random r = new Random();
      // String key = base64.encode(List<int>.generate(8, (_) => r.nextInt(255)));
      HttpClient client = HttpClient(context: SecurityContext());
      client.badCertificateCallback = (X509Certificate cert, String host, int port){
        print(
            'CustomWebSocket: Allow self-signed certificate => $host:$port. ');
        return true;
      };
      HttpClientRequest request = await client.getUrl(Uri.parse(url));
      request.headers.add('Connection', 'Upgrade');
      request.headers.add('Upgrade', 'websocket');
      request.headers.add('Sec-WebSocket-Version', '13');
      request.headers.add('Sec-WebSocket-Key', token);
      HttpClientResponse response = await request.close();

      Socket socket = await response.detachSocket();
      var webSocket = WebSocket.fromUpgradedSocket(
        socket,
        protocol: 'signaling',
        serverSide: false,
      );
      return webSocket;
    } catch (e) {
      throw e;
    }
  }

}